<?php
/**
 * Prado Portal.
 *
 * @author Steen Rabol <steen.rabol@gmail.com>
 * @link http://www.pradoportal.dk/
 * @copyright Copyright &copy; 2006,2007,2008 Steen Rabol
 * @license http://www.pradoportal.dk
 * @version $Id: PortalLicens.php 289 2008-11-14 05:34:40Z steen.rabol@gmail.com $
 *
 */
class PortalLicens
{
 	public $HASH_KEY1 		= '0c660371496407fe149ae3d5f34d44e5f67300a7772742718211054c5a4a0f2f';
	public $HASH_KEY2 		= 'c69d83be077b02447c739d8b218560f2ce0aac9fa208c400be689600e062a856';
	public $HASH_KEY3 		= 'f7d23016a3df9646dbfd01d64f8dc93e4209dd50ba36d7c031d9b569b5b3f89d';
	public $HASH_KEY4 		= '94fa1c69eb9d6140b9a6989b91414dc11b11b05f0a4fb902f92ab1b1c9e0fe6d';
	public $START_DIF		= 129600;
	public $ID1				= '4523540f1504cd17100c4835e85b7eefd49911580f8efff0599a8f283be6b9e3';
	public $ID2				= '323783be9a53a31e158ec9600626a4703e99f4e183bc1acb8772cbdf5c3a1ece';
	public $ID3				= '3ada92f28b4ceda38562ebf047c6ff05400d4c572352a1142eedfef67d21e662';
	public $BEGIN1 			= 'BEGIN LICENSE KEY';
	public $END1			= 'END LICENSE KEY';
	public $WRAPTO			= 80;
	public $PAD				= "-";
	public $BEGIN2	 		= '_DATA{';
	public $END2	 		= '}DATA_';
	public $DATE_STRING		= 'd/M/Y H:i:s';
	public $RANDOM_SEED		= 0;
	public $RANDOM_SEED_POS	= 0;

	function __construct()
	{
	}

	function validate($str=false, $dialhost="", $dialpath="", $dialport="80", $simple_result=false)
	{
		# check to see if the class has been secured
		$dat_str = $str;
		if(strlen($dat_str)>0)
		{
			# decrypt the data
			$data = $this->_unwrap_license($dat_str);
			if(is_array($data))
			{
				$id1 = md5($this->ID1);
				$id2 = md5($this->ID2);
				# missing / incorrect id therefore it has been tampered with
				switch($data['ID'])
				{
					case $id2 :
						$data['RESULT'] = 'PENDING';
						break;
					case $id1 :
						break;
					default :
					$data['RESULT'] = 'CORRUPT';
				}

				if($data['BINDING']['DATE'])
				{
					# the license is being used before it's official start
					if($data['DATE']['START'] > time()+$this->START_DIF)
					{
						$data['RESULT'] = 'TMINUS';
					}
					# the license has expired
					if($data['DATE']['END']-time() < 0 && $data['DATE']['SPAN'] != 'NEVER')
					{
						$data['RESULT'] = 'EXPIRED';
					}
					$data['DATE']['HUMAN']['START'] = date($this->DATE_STRING, $data['DATE']['START']);
					$data['DATE']['HUMAN']['END'] 	= date($this->DATE_STRING, $data['DATE']['END']);
				}


				# passed all current test so license is ok
				if(!isset($data['RESULT']))
				{
					# result is ok all test passed, license is legal
					$data['RESULT'] = 'OK';
				}
				if($simple_result)
				{
					$data = $data['RESULT'] == 'OK' ? true : false;
				}
				# data is returned for use
				return $data;
			}
			else
			{
				return $simple_result ? false : array('RESULT'=>'INVALID');
			}
		}

		return $simple_result ? false : array('RESULT'=>'EMPTY');
	}

		/**
		* _get_os_linebreak
		*
		* get's the os linebreak
		*
		* @access private
		* @param boolean $true_val If the true value is needed for writing files, make true
		*		 defaults to false
			* @return string Returns the os linebreak
		**/
		function _get_os_linebreak($true_val=false)
		{
			$os = strtolower(PHP_OS);
			switch($os)
			{
				# not sure if the string is correct for FreeBSD
				# not tested
				case 'freebsd' :
				# not sure if the string is correct for NetBSD
				# not tested
				case 'netbsd' :
				# not sure if the string is correct for Solaris
				# not tested
				case 'solaris' :
				# not sure if the string is correct for SunOS
				# not tested
				case 'sunos' :
				# linux variation
				# tested on server
				case 'linux' :
					$nl = "\n";
					break;
				# darwin is mac os x
				# tested only on the client os
				case 'darwin' :
					# note os x has \r line returns however it appears that the ifcofig
					# file used to source much data uses \n. let me know if this is
					# just my setup and i will attempt to fix.
					if($true_val) $nl = "\r";
					else $nl = "\n";
					break;
				# defaults to a win system format;
				default :
					$nl = "\r\n";
			}
			return $nl;
		}

		/**
		* _compare_domain_ip
		*
		* uses the supplied domain in the key and runs a check against the collected
		* ip addresses. If there are matching ips it returns true as the domain
		* and ip address match up
		*
		* @access private
			* @return boolean
		**/
		function _compare_domain_ip($domain, $ips=false)
		{
			if($ips === null || $ips === false || $ips === "IP_404")
				$ips == array();

			# if no ips are supplied get the ip addresses for the server
			if(!$ips)
				$ips = $this->_get_ip_address();

			if($ips === null || $ips === false || $ips === "IP_404")
				$ips == array();

			# get the domain ip list
			$domain_ips = gethostbynamel($domain);
			if($domain_ips === false)
			{
				$i = gethostbyname($domain);
				if($i !== $domain)
				{
					$domain_ips = array();
					$domain_ips[] = $i;
				}
			}
			if(!is_array($ips))
			{
				$ips = array();
			}

			if($domain_ips !== false && count($domain_ips) != 0 && is_array($ips))
			{
				$ips = array_merge($ips,$domain_ips);
			}
			# loop through the collected ip's searching for matches against the domain ips
			if(is_array($domain_ips) && count($domain_ips) > 0)
			{
				foreach($domain_ips as $ip)
				{
					if(in_array($ip, $ips)) return true;
				}
			}

			return false;
		}

		/**
		* _pad
		*
		* pad out the begin and end seperators
		*
		* @access private
		* @param string $str The string to be padded
			* @return string Returns the padded string
		**/
		function _pad($str)
		{
			$str_len 	= strlen($str);
			$spaces 	= ($this->WRAPTO-$str_len)/2;
			$str1 = '';
			for($i=0; $i<$spaces; $i++)
			{
				$str1 = $str1.$this->PAD;
			}
			if($spaces/2 != round($spaces/2))
			{
				$str = substr($str1, 0, strlen($str1)-1).$str;
			}
			else
			{
				$str = $str1.$str;
			}
			$str = $str.$str1;
			return $str;
		}

		/**
		* _get_key
		*
		* gets the hash key for the current encryption
		*
		* @access private
		* @param string $key_type The license key type being produced
			* @return string Returns the hash key
		**/
		function _get_key($key_type)
		{
			switch($key_type)
			{
				case 'KEY' :
					return $this->HASH_KEY1;
				case 'REQUESTKEY' :
					return $this->HASH_KEY2;
				case 'HOMEKEY' :
					return $this->HASH_KEY3;
				case 'SERVERKEY' :
					return $this->HASH_KEY4;
			}
		}

		/**
		* _get_begin
		*
		* gets the begining license key seperator text
		*
		* @access private
		* @param string $key_type The license key type being produced
			* @return string Returns the begining string
		**/
		function _get_begin($key_type)
		{
			switch($key_type)
			{
				case 'KEY' :
					return $this->BEGIN1;
				case 'REQUESTKEY' :
					return $this->BEGIN2;
				case 'HOMEKEY' :
					return '';
			}
		}

		/**
		* _get_end
		*
		* gets the ending license key seperator text
		*
		* @access private
		* @param string $key_type The license key type being produced
			* @return string Returns the ending string
		**/
		function _get_end($key_type)
		{
			switch($key_type)
			{
				case 'KEY' :
					return $this->END1;
				case 'REQUESTKEY' :
					return $this->_END2;
				case 'HOMEKEY' :
					return '';
			}
		}

		/**
		* _generate_random_string
		*
		* generates a random string
		*
		* @access private
		* @param integer $length The length of the random string
		* @param string $seeds The string to pluck the characters from
			* @return string Returns random string
		**/
		function del_generate_random_string($length=10, $seeds='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789')
		{
			$str = '';
			$seeds_count = strlen($seeds);

			list($usec, $sec) = explode(' ', microtime());
			$seed = (float) $sec + ((float) $usec * 100000);
			mt_srand($seed);

			for ($i = 0; $length > $i; $i++) {
				$str .= $seeds{mt_rand(0, $seeds_count - 1)};
			}
			return $str;
		}

	function _decrypt($str, $key_type='KEY')
	{
		$rand_add_on = substr($str, 0, $this->RANDOM_SEED);
		$str = base64_decode(base64_decode(substr($str, $this->RANDOM_SEED)));
		# get the key
		$key 	= $rand_add_on . $this->_get_key($key_type);
		$decrypt 	= '';

		# loop through the text and decode the string
		for($i=1; $i<=strlen($str); $i++)
		{
			$char 		= substr($str, $i-1, 1);
			$keychar 	= substr($key, ($i % strlen($key))-1, 1);
			$char 		= chr(ord($char)-ord($keychar));
			$decrypt	.= $char;
		}
		return unserialize($decrypt);

	}

	function _unwrap_license($enc_str, $key_type='KEY')
	{
		# sort the variables
		$begin 	= $this->_pad($this->_get_begin($key_type));
		$end 	= $this->_pad($this->_get_end($key_type));

		# get string without seperators
		$str 	= trim(str_replace(array($begin, $end, "\r", "\n", "\t"), '', $enc_str));

		# decrypt and return the key
		return $this->_decrypt($str, $key_type);
	}
}
?>